// Copyright 2022 jeff.li. and/or its affiliates.

#pragma once

#include <cstddef>
#include <iterator>

#include <tbir/runtime/generator/generator_ref.h>
#include <tbir/runtime/runtime_value.h>

namespace tbir::runtime {

#define DEFINE_GENERATOR_OBJECT_NODE(Name, ResultType)                             \
  class Name##Node : public Object {                                               \
   public:                                                                         \
    typedef GeneratorAdapter<ResultType> GAdapter;                                 \
                                                                                   \
   public:                                                                         \
    explicit Name##Node(GAdapter&& generator) : generator_(std::move(generator)) { \
    }                                                                              \
    explicit Name##Node() : generator_() {                                         \
    }                                                                              \
    ~Name##Node() = default;                                                       \
    static constexpr const uint32_t _type_index = TypeIndex::kRuntime##Name;       \
    static constexpr const char* _type_key = #Name;                                \
    TBIR_DECLARE_FINAL_OBJECT_INFO(Name##Node, Object);                      \
                                                                                   \
   private:                                                                        \
    GAdapter generator_;                                                           \
    friend class Name;                                                             \
    friend class Name##NodeTrait;                                                  \
  }

    DEFINE_GENERATOR_OBJECT_NODE(BoolGenerator, bool);

    DEFINE_GENERATOR_OBJECT_NODE(Int32Generator, int32_t);

    DEFINE_GENERATOR_OBJECT_NODE(Int64Generator, int64_t);

    DEFINE_GENERATOR_OBJECT_NODE(Float32Generator, float);

    DEFINE_GENERATOR_OBJECT_NODE(Float64Generator, double);

    DEFINE_GENERATOR_OBJECT_NODE(RTValueGenerator, RTValue);

#undef DEFINE_GENERATOR_OBJECT_NODE
}  // namespace tbir::runtime
